package org.onlineCode.controller;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.PrintStream;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FileUtils;
import org.onlineCode.dao.CodeDao;
import org.onlineCode.dao.CodeLogDao;
import org.onlineCode.dao.LanguageDao;
import org.onlineCode.pojo.CodeLog;
import org.onlineCode.pojo.Codes;
import org.onlineCode.pojo.Language;
import org.onlineCode.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/code")
public class CodeController {
	@Resource
	private CodeDao codeDao;
	@Resource
	private LanguageDao languageDao;
	@Resource
	private CodeLogDao codeLogDao;

	public void setCodeLogDao(CodeLogDao codeLogDao) {
		this.codeLogDao = codeLogDao;
	}

	public void setLanguageDao(LanguageDao languageDao) {
		this.languageDao = languageDao;
	}

	public void setCodeDao(CodeDao codeDao) {
		this.codeDao = codeDao;
	}
	
	@RequestMapping(value="/add",method=RequestMethod.GET)
	public String add(ModelMap modelMap) throws Exception {
		List<Language> list = languageDao.getAll();
		modelMap.put("languages", list);
		
		return "add";
	}
	
	@RequestMapping("/try")
	public String tryCode(String lan, String code,ModelMap modelMap,HttpServletRequest request) throws Exception {
		List<String> list = Arrays.asList("js","html");
		//如果可以在浏览器直接运行，则直接在网页显示代码
		if (list.contains(lan.toLowerCase())) {
			if (lan.toLowerCase().equals("js")) {
				code = "<script type='text/javascript'>" + code + "</script>";
			}
			modelMap.put("code", code);
		}else {
			//如果是Java代码，则先获取类名 --> 创建Java文件 --> 编译 --> 运行得到输出结果
			String path = request.getServletContext().getRealPath("/WEB-INF/classes");
			File file = new File(path + File.separator + "Test.java");
			if (file.exists()) {
				file.delete();
			}
			FileUtils.write(file, code);
			
			makeJavaFile(path + File.separator + "Test.java");
			
			Method method = Class.forName("Test").getMethod("main",String[].class);
			
			PrintStream oldPrintStream = System.out;
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			System.setOut(new PrintStream(bos));
			
			method.invoke(null,  (Object)new String[]{"a", "b", "c"});
			System.setOut(oldPrintStream);
			
			StringBuffer sb = new StringBuffer();
			BufferedReader reader = new BufferedReader(new StringReader(bos.toString()));
			String tem = null;
			while((tem = reader.readLine()) != null) {
				sb.append(tem + "<br/>");
			}
			
			modelMap.put("code", sb.toString());
		}
		return "try";
	}
	
	public int makeJavaFile(String fileName) { 
		int ret = 0; 
		try { 
		Runtime rt = Runtime.getRuntime(); 
		Process ps = rt.exec("javac " + fileName); 
		ps.waitFor(); 
		byte[] out = new byte[1024]; 
		DataInputStream dos = new DataInputStream(ps.getInputStream()); 
		dos.read(out); 
		String s = new String(out); 
		if (s.indexOf("Exception") > 0) { 
		ret = -1; 
		} 
		} 
		catch (Exception e) { 
		ret = -1; 
		e.printStackTrace(); 
		} 
		return ret; 
		} 
	
	@RequestMapping("/view/{id}")
	public String view(@PathVariable("id")Integer id,ModelMap modelMap) throws Exception {
		Codes codes = codeDao.getById(id);
		modelMap.put("code", codes);
		
		List<CodeLog> list = codeLogDao.getByCodeId(id);
		modelMap.put("logs", list);
		
		return "view";
		
	}
	
	@RequestMapping(value="/edit",method=RequestMethod.GET)
	public String toEdit(Integer id, ModelMap modelMap) throws Exception {
		List<Language> list = languageDao.getAll();
		modelMap.put("languages", list);
		
		Codes codes = codeDao.getById(id);
		modelMap.put("code", codes);
		return "edit";
	}
	
	@RequestMapping(value="/edit",method=RequestMethod.POST)
	public String edit(Codes codes,String remark,HttpSession session) throws Exception {
		User user = (User)session.getAttribute("login_user");
		codes.setLastModifyUser(user);
		
		codeDao.update(codes);
		
		//添加修改记录
		CodeLog codeLog = new CodeLog();
		codeLog.setCodeId(codes.getId());
		codeLog.setUser(user);
		codeLog.setRemark(remark);
		codeLogDao.add(codeLog);
		
		
		return "redirect:/user/main";
	}
	
	@RequestMapping(value="/add",method=RequestMethod.POST)
	public String add(Codes codes,HttpSession session) throws Exception {
		User user = (User)session.getAttribute("login_user");
		codes.setUserId(user.getId());
		codes.setLastModifyUser(user);
		codes.setPublics(false);
		
		codeDao.add(codes);
		
		return "redirect:/user/main";
	}
	
	@RequestMapping(value="/share")
	@ResponseBody
	public Map<String, Object> share(int id,int state) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		
		codeDao.updateCodeState(id, state);
		
		map.put("result", true);
		return map;
	}
	
	@RequestMapping(value="/delete")
	@ResponseBody
	public Map<String, Object> delete(int id) throws Exception {
		codeDao.deleteLogByCodeId(id);
		codeDao.deleteById(id);
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("result", true);
		return map;
	}
	
	@RequestMapping("/share/index")
	public String shareIndex() throws Exception {
		return "shareList";
	}
	
	@RequestMapping(value="/share/list",produces="application/json")
	@ResponseBody
	public Map<String, Object> shareList(@RequestParam(defaultValue="0") int offset,@RequestParam(defaultValue="10") int limit, 
			Codes condition, HttpSession session) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		
		List<Codes> list = codeDao.getSharedCodes(offset, limit);
		int total = codeDao.getSharedCount();
		map.put("total", total);
		map.put("rows", list);
		return map;
	}
	
	@RequestMapping(value="/list",produces="application/json")
	@ResponseBody
	public Map<String, Object> list(@RequestParam(defaultValue="0") int offset,@RequestParam(defaultValue="10") int limit, 
			Codes condition, HttpSession session) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		
		User user = (User)session.getAttribute("login_user");
		condition.setUserId(user.getId());
		
		List<Codes> list = codeDao.getListByCondition(offset, limit, condition);
		int total = codeDao.getCountByCondition(condition);
		map.put("total", total);
		map.put("rows", list);
		return map;
	}
}
